import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:dio/dio.dart';
import 'package:get/get.dart';
import 'package:shimo_app/bus/struct/request_id.dart';
import 'frame/frame.dart';

int _sequence = 0;

class SocketServer {
  ServerSocket? _server;
  Socket? _socket;
  final _lock = Lock();
  bool _received = false;
  List<int> _receiveData = [];
  bool _connected = false;
  int _notResponseCount = 0;

  Future<bool> serve(String ip, int port) async {
    try {
      _server = await ServerSocket.bind(ip, port);
      _server?.listen(_onReceive);
      print("socket served====>ip:$ip,port:$port");
      return true;
    } catch (e) {
      print(e);
    }
    return false;
  }

  bool connected() {
    return _connected;
  }

  List<Function> _listeners = [];

  void setConnectedListener(Function(bool state) listener) {
    _listeners.add(listener);
  }

  void send(List<int> data) async {
    final buffer = Uint8List(data.length);
    final bytes = ByteData.view(buffer.buffer);
    for (var i = 0; i < data.length; i++) {
      bytes.setUint8(i, data[i]);
    }
    print("sending>>>$data");
    _socket?.add(buffer);
    _socket?.flush();
  }

  void _setConnectedState(bool state) {
    if (state != _connected) {
      _connected = state;
      for (var i in _listeners) {
        i(state);
      }
    }
  }

  void _onReceive(Socket socket) {
    _socket = socket;
    _socket?.listen((event) {
      print(event.buffer.asInt8List());
      if (event.buffer.asUint8List()[0] == 123) {
        _setConnectedState(true);
        print("终端连接");
        send(Uint8List.fromList([1, 2, 3, 4]));
        return;
      }
      // send(Uint8List.fromList([1, 2, 34, 4]));
      _received = true;
      _receiveData = event.buffer.asUint8List().toList();
    });
  }

  Future<List<int>> sendRequest(RequestBean request) async {
    final frame = Frame(null);
    frame
        .pushByte(request.boardId)
        .pushByte(_sequence)
        .pushByte(request.requestId.index)
        .pushShort(request.dataLength);
    if (request.dataLength > 0) {
      frame.pushList(request.data);
    }
    frame.pushByte(frame.xor());
    _sequence = (0x10 + _sequence) & 0xFF;
    _lock.lock();
    int countDown = 22;
    while (true) {
      _received = false;
      _receiveData.clear();
      send(Uint8List.fromList(frame.toList()));
      while (countDown-- > 0) {
        if (_received) {
          break;
        }
        await 10.milliseconds.delay();
      }
      if (!_received) {
        if (_notResponseCount++ >= 3) {
          _setConnectedState(false);
        }
        return [];
      }
      _notResponseCount = 0;
      return _receiveData;
    }
  }

  void close() {
    if (_server != null) {
      _server?.close();
    }
    if (_socket != null) {
      _socket?.destroy();
    }
  }
}
